package com.gitee.zwj;

import com.gitee.zwj.codegen.CSVBaseListener;
import com.gitee.zwj.codegen.CSVParser;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.apache.commons.io.IOUtils;

import java.util.*;

public class LoadCSV {
    public static class Loader extends CSVBaseListener {
        public static final String EMPTY = "";
        /** Load a list of row maps that map field name to value */
        List<Map<String,String>> rows = new ArrayList<Map<String, String>>();
        /** List of column names */
        List<String> header;
        /** Build up a list of fields in current row */
        List<String> currentRowFieldValues;

        public void exitHdr(CSVParser.HdrContext ctx) {
            header = new ArrayList<String>();
            header.addAll(currentRowFieldValues);
        }

        public void enterRow(CSVParser.RowContext ctx) {
            currentRowFieldValues = new ArrayList<String>();
        }

        public void exitRow(CSVParser.RowContext ctx) {
            // if ( ctx.parent instanceof CSVParser.HdrContext ) return;
            /**
             * 在完成对一行的处理时，我们需要考虑上下文。如果我们刚刚处理的行是标题行，那就什么都不做，因为列名不是数据。
             * 在exitRow（）方法中，我们可以通过查看父节点的getRuleIndex（）的返回值得知当前的上下文（或者查看父节点的类型是否是HdrContext）
             * 如果当前行是一个数据行，我们就创建一个Map，同步遍历header中的列名和currentRow-FieldValues中的字段值，并将映射关系放入该Map中
             */
            if ( ctx.getParent().getRuleIndex() == CSVParser.RULE_hdr ) return;
            // It's a data row
            Map<String, String> m = new LinkedHashMap<String, String>();
            int i = 0;
            for (String v : currentRowFieldValues) {
                m.put(header.get(i), v);
                i++;
            }
            rows.add(m);
        }

        public void exitString(CSVParser.StringContext ctx) {
            currentRowFieldValues.add(ctx.STRING().getText());
        }

        public void exitText(CSVParser.TextContext ctx) {
            currentRowFieldValues.add(ctx.TEXT().getText());
        }

        public void exitEmpty(CSVParser.EmptyContext ctx) {
            currentRowFieldValues.add(EMPTY);
        }
    }


}
